package route

import (
	"reflect"
)

type dtoCreator[T any] struct {
	isStruct bool
	isPtr    bool
	mode     reflect.Type
}

type dto[T any] struct {
	isStruct bool
	isPtr    bool
	value    T
}

func (c *dtoCreator[T]) Create() *dto[T] {
	var value any
	if c.isPtr {
		value = reflect.New(c.mode.Elem()).Interface()
	} else {
		value = reflect.New(c.mode).Elem().Interface()
	}
	return &dto[T]{
		isStruct: c.isStruct,
		isPtr:    c.isPtr,
		value:    value.(T),
	}
}

func (c *dto[T]) Ptr() any {
	if c.isPtr {
		return c.value
	}
	return &c.value
}

func (c *dto[T]) Value() T {
	return c.value
}

func newCreator[T any]() *dtoCreator[T] {
	var isStruct bool
	var isPtr bool

	mode := reflect.TypeOf((*T)(nil)).Elem()
	if mode.Kind() == reflect.Struct {
		isStruct = true
	}
	if mode.Kind() == reflect.Ptr && mode.Elem().Kind() == reflect.Struct {
		isPtr = true
		isStruct = true
	}
	return &dtoCreator[T]{
		isStruct: isStruct,
		isPtr:    isPtr,
		mode:     mode,
	}
}
